﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "CmdExport.h"
#include "CommandIds.h"
#include "CommandRegister.h"

#include "FilePath.h"
#include "GbmpFileSystem.h"
#include "IDrawingExporter.h"
#include "IUiDocumentViewManager.h"
#include "ExportSetting\DefaultExportCustomizer.h"
#include "IPDFExportParams.h"
#include "ILayerSettings.h"
#include "IUiView.h"
#include "IModelView.h"
#include "UiCommonDialog.h"
#include "ModuleUtils.h"
#include "UiDocumentViewUtils.h"
#include "JournalUtils.h"
#include "IJournalCheckData.h"
#include "IUserBehaviorTrack.h"
#include "FilePath.h"
#include "IHatchSettings.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

CREATE_DEBUG_MODE(CompareDxfInLogReplay, L"回放时,比较导出的DXF。", gcmp::DebugModeGroup::DMGT_UI_AUTO_TEST, L"GDMP",
    L"2023/12/30", L"日志回放时，DXF导出成功后，自动将其与基准DXF文件进行比较，如果不同于基准DXF文件，将抛JournalError!。");

CREATE_DEBUG_MODE(ComparePDFInLogReplay, L"回放时,比较导出的PDF。", gcmp::DebugModeGroup::DMGT_UI_AUTO_TEST, L"GDMP",
    L"2023/12/30", L"日志回放时，PDF导出成功后，自动将其与基准PDF文件进行比较，如果不同于基准PDF文件，将抛JournalError!。");

using namespace std;
using namespace Sample;
using namespace gcmp;


REGISTER_COMMAND(CmdExportToDWG);
CmdExportToDWG::CmdExportToDWG():CommandBase(ID_CMD_EXPORTTODWG, true)
{

}

CmdExportToDWG::~CmdExportToDWG()
{

}

bool CmdExportToDWG::IsEnabled() const
{
    return UiDocumentViewUtils::GetCurrentDocument() != nullptr;
}

bool CmdExportToDWG::IsVisible() const
{
    return UiDocumentViewUtils::GetCurrentDocument() != nullptr;
}

OwnerPtr<IAction> CmdExportToDWG::ExecuteCommand(const CommandParameters& cmdParams)
{
    //0-动态加载导出模块
    HMODULE hModule = ModuleUtils::LoadDwgModule();
    DBG_WARN_AND_RETURN_UNLESS(hModule, 0, L"加载dwg模块失败!", L"GDMP", L"2023-09-30");

    //1-导出当前Modelview
    IUiView* currentView = IUiDocumentViewManager::Get()->GetCurrentUiView();
    DBG_WARN_AND_RETURN_UNLESS(currentView != nullptr, nullptr, L"CurrentView为空", L"GDMP", L"2023-09-30");
    IModelView* pCurrentModelView = currentView->GetModelView();
    IDocument* pDoc = pCurrentModelView->GetDocument();

    //2.1-设置视图
    std::vector<ExportViewSetting> settings;
    ExportViewSetting setting;
    setting.modelViewId = pCurrentModelView->GetElementId();
    setting.pDocument = pDoc;
    setting.ShouldExportTitle = false;
    settings.emplace_back(setting);
    
    //2.2-导出设置-设置图层
    OwnerPtr<IDrawingExporter> opExporter = IDrawingExporter::Create(pDoc, settings);
    
    OwnerPtr<ILayerSettings> opLayserSet = ILayerSettings::Create();
    std::wstring layerName = L"ModelLine";
    opLayserSet->SetLayerName(layerName);
    opLayserSet->SetAcadColorIndex(3);//绿色
    opLayserSet->SetLayerLineWidthScale(0.5);
    LineWidth lineWidth = LineWidth::LineWidthByLwDefault;
    opLayserSet->SetAcadLineWidth(lineWidth);
    opLayserSet->SetLineTypeName(L"CONTINUOUS");
    opLayserSet->SetIsOff(false);
    opLayserSet->SetLineTypeScale(200);
    opExporter->AddLayerSetting(opLayserSet);

    opExporter->SetColorByView(false);//false-颜色随层（绿色）
    opExporter->SetLineStyleByView(true);

    //2.3-导出设置-导出回调（将模型线放置在ModelLine图层）
    OwnerPtr<IExportCustomizer> opCustomizer = NEW_AS_OWNER_PTR(DefaultExportCustomizer);
    opExporter->SetExportCustomizer(opCustomizer);
    
    //4-设置导出路径
    std::wstring defaultPathFile = FileSystem::GetExeDirPath() + L"Test.dwg";
    std::wstring pathFileName = UiCommonDialog::ShowSaveFileDialog(GBMP_TR(L"导出DWG格式 - 保存到目标文件"), defaultPathFile, L"CAD文件(*.dwg)");
    if (pathFileName.empty()) return nullptr;

    std::wstring combineExportName = pathFileName;
    if (gcmp::JournalUtils::IsInReplay())
    {
        FilePath fp = FilePath(pathFileName);
        combineExportName = FilePath::Combine(fp.GetDirectoryName(), fp.GetFileNameWithoutExtension() + L"-replay" + fp.GetExtension());
    }

    //5-调用导出函数
    bool bRet = opExporter->ExportToDwg(combineExportName, AcadVersion::R21);

    std::wstring messageTitle = GBMP_TR(L"dwg文件导出");
    UiCommonDialog::ShowMessageBox(messageTitle, bRet ? GBMP_TR(L"导出成功") : GBMP_TR(L"导出失败"), (int)UiCommonDialog::ButtonType::Yes);
    if (DEBUG_MODE(CompareDxfInLogReplay))
    {
        OwnerPtr<gcmp::IJournalCheckData> opResultData = IJournalCheckData::Create();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opResultData, L"CREATE_JOURNAL_DATA(IJournalCheckData, JOURNAL_RESULT_DATA)返回空指针", L"GDMP", L"2023-09-30");
        opResultData->SetName(L"CmdExportToDWG");
        opResultData->SetData(FilePath(combineExportName).GetFileName(), gcmp::JournalCheckDataType::Dxf);
        gcmp::JournalUtils::LogOrCompareCheckData(TransferOwnership(opResultData));
    }
    return nullptr;
}

REGISTER_COMMAND(CmdExportToPDF);
CmdExportToPDF::CmdExportToPDF():CommandBase(ID_CMD_EXPORTTOPDF, true)
{

}
CmdExportToPDF::~CmdExportToPDF()
{

}

bool CmdExportToPDF::IsEnabled() const
{
    return UiDocumentViewUtils::GetCurrentDocument() != nullptr;
}

bool CmdExportToPDF::IsVisible() const
{
    return UiDocumentViewUtils::GetCurrentDocument() != nullptr;
}

OwnerPtr<IAction> CmdExportToPDF::ExecuteCommand(const CommandParameters& cmdParams)
{
    //0-动态加载导出模块
    HMODULE hModule = ModuleUtils::LoadDwgModule();
    DBG_WARN_AND_RETURN_UNLESS(hModule, 0, L"加载dwg模块失败!", L"GDMP", L"2023-09-30");
 
    //1-导出当前Modelview
    IUiView* currentView = IUiDocumentViewManager::Get()->GetCurrentUiView();
    DBG_WARN_AND_RETURN_UNLESS(currentView != nullptr, nullptr, L"CurrentView为空", L"GDMP", L"2023-09-30");
    IModelView* pCurrentModelView = currentView->GetModelView();
    IDocument* pDoc = pCurrentModelView->GetDocument();
 
    //2-导出设置
    std::vector<ExportViewSetting> settings;
    ExportViewSetting setting;
    setting.modelViewId = pCurrentModelView->GetElementId();
    setting.pDocument = pDoc;
    setting.ShouldExportTitle = false;
    settings.emplace_back(setting);

    //3-设置PDF格式
    OwnerPtr<IDrawingExporter> opExporter = IDrawingExporter::Create(pDoc, settings);
    opExporter->SetColorByView(true);//true-颜色随视图（红色）
    opExporter->SetLineStyleByView(true);

    gcmp::OwnerPtr<gcmp::IPDFExportParams> opExportParam = gcmp::IPDFExportParams::Create();
    opExportParam->SetGeometryResolution(400);//矢量分辨率
    opExportParam->SetColorResolution(400);//彩色或灰度图形分辨率
    opExportParam->SetMonochromeResolution(400);//单身图像分辨率
    opExportParam->SetIsZoomToExtend(true);//是否自适应
    opExportParam->SetPlotCentered(true);//居中

    opExportParam->SetStdScaleType(PDFStdScaleType::Scale_1_1);//打印比例
    opExportParam->SetPlotType(PDFPlotType::Display);//打印区域
    opExportParam->SetPlotRotation(PDFPlotRotation::Degrees0);//纵向/横向
    opExportParam->SetPlotOriginOffset(gcmp::Vector2d(0, 0));//打印偏移VS居中
    opExportParam->SetMediaName(L"XGA_Hi-Res_(1200.00_x_1600.00_Pixels)");//图纸尺寸
    opExportParam->SetPlotDeviceName(L"None");//打印机设备(None、DWG To PDF.pc3、Custom Device)

    //4-设置导出路径
    std::wstring defaultPathFile = FileSystem::GetExeDirPath() + L"Test.pdf";
    std::wstring pathFileName = UiCommonDialog::ShowSaveFileDialog(GBMP_TR(L"导出PDF格式 - 保存到目标文件"), defaultPathFile, L"PDF文件(*.pdf)");
    if (pathFileName.empty()) return nullptr;
    
    std::wstring combineExportName = pathFileName;
    if (gcmp::JournalUtils::IsInReplay())
    {
        FilePath fp = FilePath(pathFileName);
        combineExportName = FilePath::Combine(fp.GetDirectoryName(), fp.GetFileNameWithoutExtension() + L"-replay" + fp.GetExtension());
    }
    //5-调用导出函数
    bool bRet = opExporter->ExportToPdf(combineExportName, *opExportParam.get());

    std::wstring messageTitle = GBMP_TR(L"pdf文件导出");
    UiCommonDialog::ShowMessageBox(messageTitle, bRet ? GBMP_TR(L"导出成功") : GBMP_TR(L"导出失败"), (int)UiCommonDialog::ButtonType::Yes);
    if (DEBUG_MODE(ComparePDFInLogReplay))
    {
        OwnerPtr<gcmp::IJournalCheckData> opResultData = IJournalCheckData::Create();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opResultData, L"CREATE_JOURNAL_DATA(IJournalCheckData, JOURNAL_RESULT_DATA)返回空指针", L"GDMP", L"2023-09-30");
        opResultData->SetName(L"CmdExportToPDF");
        opResultData->SetData(FilePath(combineExportName).GetFileName(), gcmp::JournalCheckDataType::PDF);
        gcmp::JournalUtils::LogOrCompareCheckData(TransferOwnership(opResultData));
    }

    return nullptr;
}